{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from numpy import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1, 2],\n",
       "       [3, 4, 5],\n",
       "       [6, 7, 8]])"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 预备知识\n",
    "x = arange(9).reshape((3,3))\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 4, 8])"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diag(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 5])"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diag(x, k=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 7])"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diag(x, k=-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0],\n",
       "       [0, 4, 0],\n",
       "       [0, 0, 8]])"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diag(diag(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 0, 0],\n",
       "       [0, 2, 0],\n",
       "       [0, 0, 3]])"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diag((1, 2, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 2., 3.])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w, v = linalg.eig(diag((1, 2, 3)))  # 计算特征值及其协方差矩阵\n",
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 0., 0.],\n",
       "       [0., 1., 0.],\n",
       "       [0., 0., 1.]])"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1, -1],\n",
       "       [ 1,  1]])"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "array([[1, -1], [1, 1]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.+1.j, 1.-1.j])"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w, v = linalg.eig(array([[1, -1], [1, 1]]))  # 计算特征值及其协方差矩阵\n",
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.70710678+0.j        , 0.70710678-0.j        ],\n",
       "       [0.        -0.70710678j, 0.        +0.70710678j]])"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.+0.j,  0.+1.j],\n",
       "       [-0.-1.j,  1.+0.j]])"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = array([[1, 1j], [-1j, 1]])\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2.+0.j, 0.+0.j])"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w, v = linalg.eig(a)  # 计算特征值及其协方差矩阵\n",
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.        +0.70710678j, 0.70710678+0.j        ],\n",
       "       [0.70710678+0.j        , 0.        +0.70710678j]])"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 0.],\n",
       "       [0., 1.]])"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = array([[1 + 1e-9, 0], [0, 1 - 1e-9]])\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 1.])"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w, v = linalg.eig(a)  # 计算特征值及其协方差矩阵\n",
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 0.],\n",
       "       [0., 1.]])"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将数据集封装为mat类型并返回\n",
    "def loadDataSet(fileName, delim='\\t'):\n",
    "    fr = open(fileName)\n",
    "    stringArr = [line.strip().split(delim) for line in fr.readlines()]\n",
    "    datArr = [list(map(float, line)) for line in stringArr]\n",
    "    return mat(datArr)\n",
    "\n",
    "def pca(dataMat, topNfeat=9999999):\n",
    "    meanVals = mean(dataMat, axis=0)\n",
    "    meanRemoved = dataMat - meanVals\n",
    "    # numpy.cov()解释，求协方差\n",
    "    # 如果rowvar为非零（默认值），则每一行代表一个变量，各列中带有观察值。 \n",
    "    # 否则，该关系将转置：每一列代表一个变量，而行包含观察值。\n",
    "    covMat = cov(meanRemoved, rowvar=0) \n",
    "    eigVals, eigVects = linalg.eig(mat(covMat))  # 计算特征值及其协方差矩阵\n",
    "    eigValInd = argsort(eigVals)  # 升序排序\n",
    "#     print(eigValInd, eigVals)  # [0 1] [0.36651371 2.89713496]\n",
    "    eigValInd = eigValInd[: -(topNfeat+1) : -1]  # 求最大的topNfeat下标\n",
    "#     print(eigValInd)  # [1]\n",
    "    redEigVects = eigVects[:, eigValInd]  # 提取找到的所有列\n",
    "    lowDDataMat = meanRemoved * redEigVects  # 数据转换到新的空间\n",
    "    reconMat = (lowDDataMat * redEigVects.T) + meanVals  # 降维后的数据\n",
    "    return lowDDataMat, reconMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[10.235186, 11.321997],\n",
       "        [10.122339, 11.810993],\n",
       "        [ 9.190236,  8.904943],\n",
       "        ...,\n",
       "        [ 9.854922,  9.201393],\n",
       "        [ 9.11458 ,  9.134215],\n",
       "        [10.334899,  8.543604]])"
      ]
     },
     "execution_count": 124,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataMat = loadDataSet('testSet.txt')\n",
    "dataMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1000, 1)"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lowDMat, reconMat = pca(dataMat, 1)\n",
    "shape(lowDMat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[-2.51033597],\n",
       "        [-2.86915379],\n",
       "        [ 0.09741085]])"
      ]
     },
     "execution_count": 126,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lowDMat[: 3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "matrix([[10.37044569, 11.23955536],\n",
       "        [10.55719313, 11.54594665],\n",
       "        [ 9.01323877,  9.01282393],\n",
       "        ...,\n",
       "        [ 9.32502753,  9.52436704],\n",
       "        [ 9.0946364 ,  9.14637075],\n",
       "        [ 9.16271152,  9.2580597 ]])"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reconMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def drawScatter(dataMat, reconMat):\n",
    "    fig = plt.figure()\n",
    "    ax = fig.add_subplot(111)\n",
    "\n",
    "    ax.scatter(dataMat[:, 0].flatten().A[0], dataMat[:, 1].flatten().A[0], \\\n",
    "               marker='^', s=90)\n",
    "\n",
    "    ax.scatter(reconMat[:, 0].flatten().A[0], reconMat[:, 1].flatten().A[0], \\\n",
    "               marker='o', s=50, c='red')\n",
    "\n",
    "drawScatter(dataMat, reconMat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8li6FKAAAgAElEQVR4nOydd5gUVbr/P6c6TkJFBASEGcCAIAYGxIAomJhFRQHjqri4oj9c3b33rmENgLrXsLvXddc1ICqgi6LiGsCAiiIoKGENBBVFcQEDQWRmOlV3n98fPd1MqKquztMz5/M8/Qx0V1edTm+des/3/b5CSolCoVAoihet0ANQKBQKRWaoQK5QKBRFjgrkCoVCUeSoQK5QKBRFjgrkCoVCUeQ483mwTp06ycrKynweUqFQKIqeVatWbZdS7mf2eF4DeWVlJStXrsznIRUKhaLoEUJssnpcpVYUCoWiyFGBXKFQKIocFcgVCoWiyFGBXKFQKIocFcgVCoWiyFGBXKFQKIocFcgVCoWiyEkayIUQjwkhfhRCrDF47H+EEFII0Sk3w1MoFIUkoEe48flPCOiRQg9FYYGdGflM4PTmdwohDgBOAb7N8pgUCkVroLaWFTffQ897bmPFzX+C2tqkT1GBvzAkreyUUr4rhKg0eOhe4DrgxSyPSaFQFJqlS5E1NQwK6AzTA/hWL0A++L+IV16B4483fk5tLSvuuJ+ei1ex4oNqht08GSoq8jvudkpaOXIhxJnAFinlxza2vUIIsVIIsXLbtm3pHE6hUOST2lqoqUHU1lKqBwAo1QOIhvupq2v5nKVLkd27M+je27jqg3kMuncasnt3WLo0z4OP0d6uDFIO5EKIUuAm4FY720spp0spq6WU1fvtZ+r5olAoWgtz5yKjUcOHZDQKc+c2vTOdwJ9L0kgJFTvpzMj7AFXAx0KIb4AewGohRNdsDkyhUBSIDRsQ9fWGD4n6evjyy6Z3phr4c0kruzLIFym7H0opPwU6x//fEMyrpZTbszguhUJRIPTefdBd3sTsujE+lxdXVW9cje9MNfDnisZXBg13leoB0AOxK4OtW6G8PD9jyTN25IdPAcuAg4UQm4UQE3M/LIVCUSjmVA4lKoThY1EhmFN5TJP79N598Lm8htv7XF70qt5ZH6MhrenKIM8kDeRSyguklPtLKV1Syh5SykebPV6pZuMKRdsgoEf4y7LvmDB+KnXuEupdHgDqXR7q3CVMGD+Vv7y/pckiYqqBP2e0liuDApDXxhIKhaJ18+TyTfj1CCt79GfI5NmMXr+Eyl1b+WbvbszvNwyfuwSXHuGfH3zLxOOrEoH/5fFTmfnsVISMUqYHqXd5kEJjwvipfPH+Fs47qR9elyOnY085JdSGUIFcoVAkCOgRDuoS1353YG3lONY2/K+q0Xb+UBhIPfDnkjmVQxmb5Mrg0pyOoHCoQK5QKBJcPeJArh5xoO3tUw38uaI1XRkUAiGlzNvBqqurperZqVAoss2MJRu5+7XP0COS0pDf+MrAIbhhVL+cXxnkAiHEKilltdnjakauUCiKntZyZVAoVCBXKNoZAT3CtJfXMuWM/m0mzZBqSqitofzIFYr2RDssX28PqBm5QtFeSMfRUFEUqBm5QtEeSNPYqr25CBYrKpArFO2BdMrXVRqmaFCBXKFoD6Ravp5HF0E1688cFcgVinZASsZW+fQXV7P+rKACuULRysjFDDUlY6t8uQguXYrs1p2j2qB3eL6vMlQgVyhaEzmYoabsaJgPF8HaWhg1ClFXS1lr6CqUTQpwlaHkhwpFayFH8sBUja1iLoIeSvVgi31lzUXwjjuQdXUYXSPIaBQxdy5MLMLWBwWSeKpArlC0BnLY3casfD0qJZ6fA/Tay4smRKJ8/Y06D6MMgjhkyUWwthb++lfDIA5F7B1ewA5FKpArFK2Bhry03RlqKmX2huXrtbUsueN+1ixexYDh1Qy7eTJUVLDrhx2c8IerjMcBXDnmRj7J1EVw7lwkmAbyoMOJVoze4Sl+htlE5cgVitZAKnnpTHOwZtLChQtZN/YS3CazcZ/TTbfd2/E3pGHSZsMGRChk+rCQMn9dhbJJATsUqRm5QtEKsN3dJtMcrMXlvzztNAZrDlzSWLFSFg5RHd7B2i4VGbkI+npVIV0eygxOGBKYMXgMDxWhd3ghOxSpGblC0QqwJQ+00HcHTj2NwE8/Jz+QhbRQAK6ouVzO5/Jy9vjhLLhmWEZOg7/XDkEK49BT7/Jy/7HnZz7rLwCF7F2qArlCUWDsygP1OU+ZBmEtEODbC3+VPM1icfmfjGwEo4Ae4c3NfvPXeu40Ap4S+nYuLyrv8HSaVmcTlVpRFD3F7q9tVx647t3VHG4ShN0yStXCF5Hdu1umWawu/80ICY2Qy5OVdmlPLt9EVErr16oJxg06oKg6+RS6d6kK5IripraWFXfcT8/Fq1jxwR71RTFht7vNj/4e+CyCsCsaSaRfzKRuVg2KjQhpDl489ESmnHJlVoJRW+3kU+jXpXp2KoqXhoU/f0CnVA/gc3kp8brarL/2rNc/YeyZQykP+S23k2VliPvuayF1C+gRhvzxTQ768uOmDYqdbkrDIUPZXJ27hNE3zKVs370T940a0LXVduMp9qszM1TPTkXbpIDFF4WgeZd4tx7EbaIuMZO6WV3+b+3QiYdeuNOw+/xO4ea1q47NemDMetBtA1dn6aICuaI4KWDxRSFoHoRvW/ggZ65fjNtAZWImdTO6/F9cF+TH3UFKgz7uPuESRny1AhAs6jOYeYeNzF1uN9tBt513P1KBXFGcFLD4ohA0D8L/GHstp9+1DLdBmsWsjN6owvP+RRvY9OJCpj18HTIaSczGj966nsChA1jXbSCQ5dxutoNuO7s6M0RKmbfboEGDpEKRDUIPPSzrXV4pocWt3uWVoYenF3qIOcMfCsvDprwmLzr3Nul3uGRQaFKCrHO6Za27RI696G552JTXpD8UTr6z3bulrKgwfB/9JaXSv3OX4fFvmPexvf2ncDxZUSFlbW3q+3zkERktKzPcZ7SsTMoZM1LfZysDWCktYqvSkSuKkkIWXxSaJ5dv4tCNn/DQC3cS1TTcMkpIc+CQkivH3MjKHv3tF9RYFAgZatMztQfIhdd5O7s6M0IFckXRUejii2yTahOCyM8/89gzUykP+RNWs+5oBG9EZ/qLdzFoXycH2S2jtwiCjbXpLF2anfZvOQi6KXU/aqMkzZELIR4DRgM/SikHNNz3J+AMIAR8BVwmpdyVy4EqFHEKXXyRVdJY9Jv0/SqkU4CBt1WJUzCv4+bEQm8yZUiyAqGENn3UKABEXV1GeWg7fiSRFNUsVtr4rNjuFgF2ZuQzgdOb3fcGMEBKORD4Argxy+NSKEyJL/z179aBqsourB01jgUXXMPaUeOoquxC/24d7M9IC8AuX4iRf3mH2jffbjnD7dadh/4403p2bndW2ygN8uiEmwjsbDnXskpRNUaGdKSJY2EqKZFkKbFnuwxMKXXT1q7O0sYqgR6/AZXAGpPHzgb+aWc/arFT0ZaxtQi4ZYt877ga+VGXvlJ3OAwX6IKaUy797dTYwqABthZ6lyyR0YoKWe/0xPYpNKm73VK+/nqT8R425TU59qK7Za27JLFomtbthhuSvh/Nj1fnio2tzuWRte4SedMpV8pad0nitdW7vDJaUSHlkiWmb+cj734l+/5hgex1/XzZ73fPyt+ffo38x9Bx8venXyP7/e5Z2ev6+bLvHxbIGUs22vwUWyckWezMhvzwV4Dp6VgIcQVwBUDPnj2zcDiFohViJ0XywAPIyZM5hpjToFlNtTsapvrvdyAf/YuhJC9ZKuHZLgO5sOaUJnI8t4xCKIQ87TTE66/DqaempE23agThc3pa6tZra1l+29/puWQ1Hyw7iuG3/oYnP9pmmhJ7u3c1b8+Y1KRq1U7qptCl8a0FWyX6QohKYL5syJE3uv8moBo4R9rYkSrRVxSanJRwm1gFhF56mZu374VA8Icj92KvvlWmwdAMWVGBaBTETMvsG1ViDti9lSlvPYLw+Yx36vXCtm3c/+F3vLrm+8Tdvh0/8fJd5xtaAFgF8oDDxdxXVnPpqQP2vB+jRhHyB/BEwgQdTtwlXp6/YzqPiR6G+zh12XyueP5vlIRa5s7NLAfaEzkr0RdCXEpsEXSknSCuUBScXJRwWxSjOE49lTO79QMgVP9jWruP+AM4Z82CyZMBewu9pyxeYR7EARmJEJ7zFFs6Hc28htL7+AliQoMFQOMThCsSwR01n9G+cvBx/CXuihjwwWmnIXw+PA2PeyJhqKtj7B8uZ+wPPxgvim6ZDwZBHNqPhDAT0grkQojTgeuB4VJK82+MQpFHLGfbWagmNNy/hVWAQw8xbNPHgPWM1gpnWEf+7r94eFcZE6672FYqIdytu+XxhK7z3WNP0pPXEyc0q7SHJxzkhsUzDTv6+FwelvccmNCtT/xoAdLnM7ZO8PkQjU5KjSlkd522gB354VPAiUAnIcRmYAoxlYoHeEPEcnXLpZRX5nCcCoU1VrNtmyXclicCg5wvFRXWChKTfzcnWZAXeohf3fprPvjxa66+438MnQcbj331xrcs9hY7XpeV73NVJJw4oe1z+8Mc1CWe9mh6gti2dRvXvzvbcF9RofHhkJM5aN8GldD8+eYnEIAFCwwD+TOdD2OsSXei9iIhzAirldBs35RqRZET4goNM7WDnRLu3bvlu9f9r3zg6LHy3evulP4dP+1RXCxZIqPl5TLgcEoJMuBwSr+3VAbefsdSQWL3Fm1QlSTbLiQ0GS0vl3LJkqaKkEZjf/t//ihnHT0m9XGYlMc3V5rUNyhNgppD+h0u+cvxtzWxAwifeprlccKnnd7iGIG335G17hLpd7oT74cE6XO4UrccaKOQRLWiArmiuLHj3XHdddZB7KKLmp0IPDLodMvnDx0u37t2qpQlJcZByemST895U9a6jR+3G8SnnTRRjr3obhnUjOWILZ5TUiKX/naKfODosfKjC6+Q0fLyxNjrXF7pd7gSQdHoeJYntGY0lveZebucd/E9CXnfu9fcan4MkO9eO6XF5xcsNT7J+h0uOWjy7DYjIcyEZIFclegrWhWplqvb8e6wLOF2epDz5jVraBzEHQ5x9rrFDLrvNqTfuJGDFtY56+LT+b/jLjSVEibD7/RQ5yljZY/+3D7i1wQdNpat/H6q77udqz6Yx8A502PVlg1jL9MDeCM6nrBx8Y5p2sNkQTGek6/u6GT6i3fijegJH/SycIjykJ/HnplK+OefCegRrnUPxO90m7xWN9e6Bzb9bOfORYSNF1KFEFy0Yw17l7qKrodnvlGBXNF6SMeQyUaV4zOdD0Mzyb9qMkrYIkPtwXghE2JB0RsJ84d3Hick0pMyloaDVO7aigBeHjgS3ZF8SU8AnoZgaiUJDDhcTSodA5rTdJw+lxdfz8oWJ9GrRxzIgmuG8dyORZQEjU9oJU7BpO9XMfO9b9jp8HLJebdT5/ImTkpBh5M6V+z+nZqHWe9/s+fJa9fiChl4DQCecIhxX77HpFem84et73P14K7mb0o7R/mRK1oHaapKkqkdtFCYs84fCQ0FNPGFRb/DRcTh5I2+Qzh73eKMhu6U0aQ/JLMFzaDDSb8fNvJ45GNucPeLyf+emUKZHkhL5RKnJKIzffAYvty3J5W7toKES1fPx2PiqRIFXlz2FT2/eMN4sfjee5PO5peLwwBiypernzCURgIs27iDScP7ABDevgMHxu+NBLquWs5VMtLuGkWkigrkisKTQWMAyypHQHvggSYFLqLR3xN//TAjv1rBqRuWG0rr8oE7Euakr1dTf9863hSCCeOncvfwS7n1rem4ZLoJm9gMvL7PQaw9ZjQbAz5m33qO4clOEjupaVIy5um/UaYHWwbNuXORQpgG8qDDhVbVm+rKfdhWF38fzassq3vtk/j3uqCDgSb7FYBLxq4O2l2jiBRRgVxReNJs29a8j2XzKscnjqzhktULDA8pHQ4u3rGGF4acjFw0I8svqCWWkjxiuW2A2c9N443Bp2UUxAGk0Oh42cUsOHUA3H8/ekQ33C6kOXEg8YT3nMhaBM0NGxAmhlkAQkrmVB5j2IHIioAeYV5gLw50uCgxGV+L19UG2/hlA5UjVxSeND2qm1c5Ths5iQeGjmPayEkMmRzTPZeZpBJKQgEmHwA7hIcJ46cScLjSXrDMJiUiyuhlL6U8lvj2zV3/gu8sRv7Xf+EKGwdKTzSMO2K8iBhfLPb1qkrk2o2OO2PwmCYOg3YXrJ9cvol/9T2OiJ0F3gZUlacxKpArCk66jQGa29luPKmGn7oeQNVPW7jo6/eR3XtYBqCPvv0JuXs3fXZs5umBpxDJKCudHUQggCNifyT1Tjd1Li8PHj2uyUlsZY/+aHW1RE6vQejms12z3D00BM116/i9dghSGIeKepeX+489b09HohQWrOuCYeo8pS0saIMOp+mJrL00ikgVlVpRFJx0GwM0uZRfuhRZM76JcRVCIExSFAI4/NnHWCUfQwrwRCPoWAe2xtjdLlVS2W8UWHjgUO49/iKO+c8aKn/aSolTcGjX2CLlZU89jDOD3L8E5D/+wU/ndjX0YImbdAU8JRzcuZy9Vy1H1kwyXLAOHH1Mi6rZco8ThyZa2AJ8V96J6xfPpNzgaioqBJfU9eJxPZI907M2gC33w2yh3A8VzbHj5vdF38P58KaTDX+4AT3Cnc98yNSrTkMYzP7CQsMhTfLvmKslIkLDKaOWgVUCIc2BJxrJWWBPRhiBA0nQ6cYbDlHv8lLq0kBKwoFQYrHQiIgQOGz8/uvcJYlU1dhP32LExhUgJYv6DOH5ASMIlZZxy/ADuGTcccYz8PJy3rv8v/lk2RoGDN+jiLl/0YYm7osAUSn5/PtajvrP2pbfBwRPHPULAPoNO4oT4zYJ7YBk7ocqkCsKyowlG7n7tc/QI5LSkN+4bZtDcMOofi3atgV27uLR39zJocveZNh/PsVpkAdON8DqwsHj1WdQvXkdR373hWnADwsNV0PzY1c0QsDhpCQSTvm4sXSCQILthb9M0IXGawcdw4iNK5MqdvxuL9PPuYbNnXsy7eHrkNFIIrgKzcH/u+h2LtrLx8kP32nouiiBkMOJJxJOWPyayQjNvg9IySWrFyCQDcf2Umqxn7ZGzmxsFYpskHZjgIULcZ5xBr8ORwwbIcRJe5Ys4D97dWXCqpctFSeuhsKc+BgcEkJouDCuNjUijOCeYZfy0qHDeXvGJMhDIHfKKCM2rjJNPTWmJBTg2v11mHEjBPcE6vgJYPrM69l1YD9T61xBg5UtyWWERt8HI/lkmZIjNsWqfj/bN+W1osgKr79u6ueRzduH/Y6WwQajrFS8U1LdNm4ONf6iu+W0kybKaKPHoinuM9Wbz+mWfs0pdSFMt6lzeaV+8cWmxmOpvm6JubeLIXZMz9o4KK8VRTGRVLpWWwtnnpnWTDukxXLsdpKJQYeTI3rsbSrNM8Mqnw6xlIZstm1JRKc85Gfm0zdzy9uPIho91vjfucAbDuGMhnFKafq+SCF4ZXPQVCIKqY8xJRlhmvLU9oQK5IrWgx3p2ty5yEjqHdElsK5TJSHNYSvoiGiU9Zt3ZE1bLoipTOKpGCNKInreF0wFe/Kr8WPHX3O9y0Ody8sTR9ZQ8c2X9gy9bJKKjDBdeWp7QgVyRd4xnHUvXYrs3p1B997GVR/MY9C905Ddu8PSpU2fvGGDqVsemM+2BdB/20ZcFvn0xvvQgMPWr8xqYI3/2JJVeRaakOZgUdUgZh11BgCXrJ7PSV+vTvnqBMw/j7is1A5zKocSTSJPbe+oQK7IL0az7sZeKwkr2UBMTlhTA3V1iafrvftQ7zQu8gHrYOiS0t5snNhiYDqBNX8asNzhiUbY1asPEz56hXI9kFjUbD5jt4PfGZvVN3ZhbFx5mqz6M27D0LxoKNX9tHWUakWRP8wcDq+6KqnXSuCSCUx7eS29ug3ml5rx/EMSM3Dy5kH1YUbz15CKDLFQWvTm6MLBmQd4cKwQYKBMDGlOHNGwYfCIv4bGdQDrOvc2lpXG+3w2k5U2xk6zaaP9WLbta4OoQK7ID1YOh/fea1pGLurrefeFd4h+9gM9l6xmU8duXHXWjTz44p2IaISycIiQ0IhqDq4+8zr+uuD/8iLfs0trCc5gfywRTeMzv5MjTBYYPdEwuuYAgzSVrjmZOWg0X+7bMxFoBbB42BmsLY/Npi1lpc1IS55q1b+1jaIKghT5YcYM5G9/a6g+aK7iaEzMdUQS1px4ouHETO/KMTfSbff2FrOz6s2xikBXRE9ol4uJXAZ+O/uWwPyDjyfscnPa5+9RalAsFF/0NHp/610ebhs5iXeGnUGn8j0psFEDuqbkjJg2DVd9ja0arAqQigVVEKRoHdjsNt8cR0OYd0RjQSNRhPLiXVx8+/Os9cTm9xV1Qfy7g4lL8LGfvsUtix6xLBbKBzqCWM2mPXI5e7cTxIMOF2d8vpR6p5sSs3ZxUpq+r2V6kEHhHRwwtFd+AndjMvC1L3bUYqciL1hJyNKhxCmY13EzC64ZxoJrhnHx0F4M6ujk15+/xW/efxrd6WLymTfkfPEx2f6lEPhttG/LByHNQVAzzhfHZ+vx9YWycKjhWijW1zT+/IDDxewjR5u6SvpcXs4ePzxnQdyyzsBG/9a2ipqRKzLC7qKSlcNhOjQvBLna/QOT79jjfljv8uCIRhPeJ83JVgojHuzMvFhePfhYTvlyRZNtrFJJucQVjVDv9OBJ4SolpDlwRcKEhIY7GqHe6eD8T15HmJzBrNwqMyZZ7rsdFw6pGbkifZIU8MRnT7t8IUMJmZXvdDJ8Ts+eQhAD+WKZHsQb0Q2DOMSCaCQLJ5ZkJ4RffPYepeFgk20KtfgZ0BysOGAAIaGhN/iLS6xfgycawSUjuBsKmcrCoQZ7WZmRrDBlbNQZtOfCITUjV6RHsmbJjWZPL84/GK3jkS0kZDu8Hbj5ncfSOrwmo3tmflat4jAOUiHNwTd778+BOzdnFFitnhurmjQ+VRUimJdEIwz/ehUa9q8KTK82hOCu4RMIOd1pyQpTwmbuO11f+7aACuSK1En2w3ruOeS4cYkgX7/ay3hNY8qke1jXZyBrK8fxqZQc/vpzhBvsX1Plrd6D+cv7WzjvpH5401hIdUcj9N65pdVIA/NFsurS5phtV6YHGUgts0ZNsudWmQk2eroGLplg2b91wvipfBH/vrRBXbkK5IoEtosorH5YkQicdRYiEEgE+XjfzHsev5GpDy7kxnMHM/O9b+CprWkFcQl0rv8Jvx5h5vvfcOiazQwj9Vlu+omd9oPZjDy+qHnuFcNyPwgbue90C4faCiqQK2KkUkRh9cPy+YhqmrEm3B/gxFsms3rlGZT+WMeAbz9Na9FRAB4Z4fC9HJQ+8gDHvvJUu5lZt5YCo3ymKvTefdBd3iZ+5HF8Li+uqt7p+9q3Faw8brN9U37krZQlS2S0okLWu7xSgqx3eWW0okLKJUsMNw899HBi23R8qTP12I6CfLfqCBktr5CBFP3Ci/0WzvC9S/Xmd7hkrcsr61weKUHWuTyy1l0ix150tzxsymvSHwrn/Os587WPZa27xHB8te4SOfP1T3M+hkJDEj9yNSNv76RRRGG1qGTXlCpTBn/zKUJGMLfPSp/WMus1It/Z3YimcdeJEwg58rCoaUDcNKu95r7tkjSQCyEeA0YDP0opBzTc1xGYC1QC3wDnSil/yt0wFTnDxkISEycm7jP7YQUdTtyRcF4CoAA0m/ntdFM3EfIfNHNBpielMj3IAfU7eLTmCvarSN0rJVPae+7bLnZm5DOB+4HZje67AXhLSnmXEOKGhv9fn/3hKbKF6UJmikUUZj+sfj9s5KSvV+fyJSQICS2ha84FkrYRxMG6YMkOPpeXX116CpOuODmLo7JPu8992yRpIJdSviuEqGx291nAiQ3/ngW8gwrkrReThcyAHmH+bi81SRaSGheYm/2wQu+/zPHffGTZASdbuGTUdnAyspU1ur/5c9rKjBxi7eVEQ0h3yWhKr63Q+uurRxyYf8+WIiTdHHkXKeV3AFLK74QQnc02FEJcAVwB0LNnzzQPp0gbs8Kd555jxVur2LXiIzQTCaDRj9jshzXr4L2Qz/xfjl5EjHqHi9IM26FFSP6l1xEgNByybTQrcMso0weP4ct9e1K5ayuda3dS84Wxs2H8BOlzeYiqHHTRkPMSfSnldClltZSyer/99sv14RSNsei8I087jUH3TuPyVS+BEEhImDtZlVsbmRYF9Ah/em8Lswf9wjJzLRv9tZfhbvrcgDtz0y2njWM7kWwr3avNqMyDDiehnr3Yy+vAHQ7hkWGcJn1PBRBCoEWjXDnmRlb26I+/IQetaL2kOyP/QQixf8NsfH/gx2wOSpElLBYyBSRmZN4Gu1IBiZmb4UKSSYpm7qK1TF74KJesfiXpkHQ0XKSefhFAR39txoupdlIyAuhWvzPDI+UGXWgxnb40t5JtTkRoXPHKI0RDYbyRUOI9MEszuZEQ0RNWwQFPaZMcdHvrvlMMpBvIXwIuBe5q+Pti1kakyB4WC5lGSIcDf5+DWHvM6JYLSWYpmrvu4oL//j2ugM9WgHSmEcQbPz9TWqusMBnx4BvVNHThQBPGgbzxiSp2leUGBG6/L7GNaPbX7OQWtwpurFpqj913igE78sOniC1sdhJCbAamEAvgzwghJgLfAuNzOUhFeui9+6A7PZSGDRovGlASCnBtpca11zQru66the6DjLXmkyfjTmFMxRpIC038ffNEwngI43N68DnclERCTQJySDhY07UvP3vLWdR3MELCDYsft7XvFvc3Vy0lM0pTFAw7qpULTB4ameWxKLLMnMqhnJeCiiTocKE1U6kAabkLpooEwpqDKKTkl91uETEHyOb2uB4Zof+PGxl+1aP8vFcn/nvRY4muSqnSRLXUjrvvFAPKj7yNEi/cefXgY20/R0jJnMpjWj6QZpu2VPnFJfeiO1OZ37dfSvWg6YKlJ6Lz3sOX89npFUy49JS0OzPFVUtAu+6+UwyoQN5GiRfuLEl8k0gAACAASURBVO85EJ9JW67GSGDG4DGGTQH0aNRUwZEtZUfQ6ebozet44sgaQpoDNSe3RmLtde7UQ1BTwzNdBhJNsYGGoWqpHXffKQZUIG+jxAt3PhxyMlGR/GOud3m5/9jzWkrNamuR/3gg57ltbzjELYtmcOnq+bijkSaqikJiZwyFGKedz0NGo3zx2FwmjJ+Kz+lJ3l8UCAuNWUedwZDJs5tID/XefRK9O5vT1rvvFAMqkBcQy0ayGXL1iAOZd9Wx7BCeFi3WGuu4E7Ovc6cR8JTQt3M5tQE9MS59zlOEw+bjy1YdpwTc0XBCEqlhHqwkkB9Xl/yZgKWC3ROHqK9n/+1bWL9fFVEh7KmKZJQJ/15Av/0r6N+tAwd1qcAfCvNmnZsSk0XzJikYRUFQ7oeFIg8yLjNflK0VnUBCt7rtTc2HNMEF/fah6o15rFm8ikfn9eWUrZ9wkMVimR0VcbbdBAUxVz4tGmmXMxG772W9y4u/VxUXfrMspfe/JORn3o634a67AAjs3EV41P8zXey+csyNfKKqPwuKCuSFIE8yrsa+KNtqPbw06HQAyoI+Tl27GCElDiHpXO6mrFMHDv3qE84fcy5hPcywcBD9Qw1nFrxTrIKIxF7ZfHPaqrLFzknP7olRCkHHyy7md289AS+09NIxQwDcey/cfDOUl7Pi7gc5yuR74Hd56LZ7Ox8oB8KCogJ5vsmjjMvQF2XpUmTNefgDOqV6AJ/LS8nSmYjnnoObbwR/fUIXng8DLAEJQ6f2TCzdJZDIpFc5yYK43+Ei4nAmfFLG96oCE2M0q/HELYxLN31tKmEs1YNUh3ewtiEFoygM7fHKtLAUUsZl4b3CWWchw+n/ENMNwxL73uK5GkNrQReaZRCXxLT+Qc061AvgxF8/nFisvM5xSMrKFREKJZQoA0+qNpUwxnt3LrhmmHIpLCAqkOebLMi40l4ktTqJhMMIvz+1/TUi3Ry4yOC52RpDoYmnSjxJ3BajCCafeV1SrX3U4eDiHWvo360Dvfcr45Wv61sseNe7PAQ1h+nJL+hw4uvcFYgVlpmdCNRCZ+tABfIcYRZs9d59LGc3SWVctbWsuPkeet5zGytu/lNslm0Xq5NIOJzSjLbYZ7+tCbsnIAeSv87/C1eOuZGQxay8tMFqYcFlR3DhJwv5/TuP02fHZk789cNMGzmJB4aOY9rISRx31ePUm3wX3ZEw2o1/IPjOYv6y7DvDE4GZQ6Yi/6gceS6wUKRY9btMauKf4SKpVTdySG1GW6yz32LHFQ3Tbfd2bh/xa25+ewaeSMt0WL3LiycSwdG9O+MCOmV6gHqXhylvP8qUSfcws/MZ/OwLEYxIJpw7jZnPTKFMD7Qo9/cGfYR+8QvE/5ulWq21ckSsQXN+qK6ulitXrszb8QpCQ7BtspjodSFeeYXA0ccw5I9vctCXH5s3ku17OB/edHJLGVdtLXTvbjwDr6iwtUg66/VPGHvmUMpD6adQFNknVXnmMydfxIPHnsvLd51v+FnWuby4nQ7cfoOrr4bvyox//8jdr32GHpFcvGq+6Ukh4PHy8NnXsPCY0ZZjGjWgq8qR5xAhxCopZbXZ42pGnk2SKFKefva99BvJptgkuTkBPcKfDZom57r/pcIcCYS0WKsLu3LKoMPJ6HOGcccPsUIvownBE0fWcOnqBYaulPHvSqDqhIQ0deDK3YZBHMAbNHHEVLQqVCDPJkmC7QFvvMxBPeM/iBQbyaa4SNrc/H/uorWM/nABPXdu5e4TLgEE+9dtt2z71WT8qHRKtokv9EY1B0QjTRo+mL3XuubkBkc//Hqd6YTgN+8/bZ4+a/iuXD1xYmIGrXvW43v3edt9WxWtDxXIs0mSYDvSVcvINGc2VvntFj+25jn6kUdxwdnnoIfDiZmb0BxMmXQPz+59AKfftSzp8YstiBfDiSduSxD3OWjc8KF59x4J+J1uJpw7jU821dG3czmaEBhNCIJbe1O/2mOo/TYKzBmt2yhaBSqQZ5GUgm2K2P6xNV8QXTUfeU8QNyQuteM/8Hsev5GhV8+OXaIbLHgVM8XwOqzGGH8sgmBLh/1Y1b0ffxwxke3lHdGiknGDDjBcXAzoES7T/Vz+r/sN99s8MMftjpun3Jqs26jy+1aPkh9mkVzpbeM/tqQSsJ27Whb8hIOmASOshxnx8duxS/Srn+DBo8cSEg70BrdEJTEsPBqSnrt/5NQvl/POI5M49rv1dCr3GKffamtZ/oe7OeHZ6TxxZA11Lm9SuWBzP57G8sTmDoiK1ouakWeJXM5szMyvmi+Srrj7IY43ydEb4Qr4OTK0g0UdPNRta+i5KcARVSE8V6Sa8olvG7+KmvOv22DrVgKeEm58/pM9DZAbrsQGB3RObJAbSgSzjhoNQhguqF90dE9e+miLZZomjiq/b92oQJ4l7AbbdPS2jc2vSgJO9vragZCSvbwODu1agd8b08iUvr8xpWbL8fJqh38bo6ZNpCTkb6ElNqMYctCtkUzfMxmNImbNYsW3u/esgVx7SeJKrKxhu3jgn/DRq1x8+/MEPKVNAnN41y5W3Pw0oxavYsBw1US52FE68ixx/6INvLrm+6TbZaS3NdCoaw4N8eoreE4cjn7f34j+93+bSsmaU+cu4aVn3ubCi09JrUJUkTLxX1lIc2Ts3CjdbvxS21On0GDeLgIt12ZkWRnivvuaSlMtah1UE+XWSTIdOVLKvN0GDRok2zr+UFjeMO9j6Q+Fs7vj3bulrKiQElrcdLdHyhdekMGSUhk1eLz5LeBwylp3iRx70d3y+tN/IyOlZUmfo272b1afQbLPJ5pkOzufb4vbDTfY+h7Jigopa2uz+71VZAVgpZTmsVUtdmaTTHxQkmFheOUIBZFjxuD2+2xdur/f63BqLv0r53/0Or9d8iSaz346JpvIghw1M+yM2eozCDrd6MLcrCrkcLK41xEEHanpm8z218K/RzVRbpOoQJ4tli5Fdu/OoHtv46oP5jHo3mnI7t1h6dLs7D9JJ3v7XWM8RPfZh8WPTGLs2kV0rf8p7wE1frxiybHLhtuGjt0JOTJbVvKGQ6zp0tv0tXsiYdbu35dfnn9HC4VSSHOYPs/s/hZqKdVEuU2iFjuzQGDnLjj1NLx+X86aRSQzvLKLlDBi1Zu2FzVzQbEE8DjxAp3Kn77LuNlGvcvDth69qd/xrWHBTr3Lw386dmuyaH7g9m/ZJ7CbzrU7OXrzGmNPFKcbpCSiaZZqqVzWOigKh5qRZ0ptLd9e+Cu0oHGJe6qXq2b2t1YadSvis9+4jnjlAf1T3ociFsxdMpr51YvQeP3i3yKF8U9PCo3l1SfTv1sHqiq7IA86iIs+Xcioz9/jhE0f4TZZyA5rDo6/8tGkOnDlLd42UTPyTGhY/a+q8+EyaQqQ0uVqs9L6wddfybR3vuX60w9JaNSffPpmPBHd9qw26HAx+6hf8OW+PZnfbxj/fPqmopsRtxUkIKIRNn34ianh1YTxU9kh3Lx61bF4Az7o/gsI+hL7aFyyL6DJ83ZWdOTT08eytiFQN9eBqyrOtosK5OnSyOnQ6lLU9uWqQWm9869TGNL3GF6cfxxaxyNZ2aM/wyY9ypKHJ+KN6C12Idkjb2v841zZoz8Hdy2nStP4qWsP5HdftPtgHg+EqdI8kOoi1qDazr4EUBoOMfPZqQyZPDt5vcFnb5masIUcTt7reTivHXzcnudpwrR0H2DGko05q3VQFBYVyNPFwumwMbZMh4zsb8OxVM3Z6xbj27Cc8ZqDWyfdzfMdqrhjxERuf+MhwMBgSQhCmpNZR53BY9VnMvKrFYz88kPKDj2ES84/gcDa5AZZ7YFsnMgkIKRMeV9CSi78ehnLThpjXUlpsTDpiYTZ3ucQ1o4aZ7sCs3FhmaribGNYaROzfcu3jjxnmm4ppbzuOkvtblBzJLTah015zXoMjzwio2XJtdzB0jI59DezZa27JOm2fpdH1ntKZJ3LIyXIOqcnPQ2yuuXm1ljbbULooYdlvctr+Px6l1eGHp6exS+0ojVDu9WR51LTjXXvzZDQePHQE+2bDlnMvBoTCUe4bfk/MVch78GjBykN+hPKiDIL86z2QjjP74DZp2SrNytqYVJhn4wCuRDid0KItUKINUKIp4QQxpEt3+Ra0431jyzk8vDAOddSVdmF/t06cFCXCsvLVauTQmNKQgGO/nYNJaHkEsT2HrSbE9IcvNzvBEImapGsHkto1Lm8+J0ew8ftBGHbjpeq6bGCDHLkQojuwDXAoVJKvxDiGeB8YGaWxpYeSdqtZUPTbWf1P6E8sLH6b+U13pyKH7bkxbBKAmGhJSR3xXxikMCvxk3h390OYdQX70PEWgsuifV6iAgHbhM1khkhzcGLh57IlFOu5NAfN6atDsmlCZui7ZHpYqcTKBFC6EApsDXzIWVIhr0t7ZDNH1mLk0I0Qlk4ZLq93YCaafAVwDd770/vn7ZQ7EI0n8PFmLXvcNymj1nU+yhGbfggaVOHpwaezpjPFuNOsVF1WHNyz+jJ+KU7o++HWphUpELagVxKuUUI8WfgW8APLJRSLmy+nRDiCuAKgJ49e6Z7OPvkoQQ5mz+yJ5dvQqurpc+OzTw18FT2CdTi1nVO/XI5Qko80eT7iOdiE7piBJqUCeVLOkigqg0EcYCyiM6Z6xfjbtQX0woJjFv7Fk8cWcPlK18EG89p/OxwRHJI94qMPL6vHnGg6kqvsE0mqZV9gLOIfTd3Ac8KIX4ppXyy8XZSyunAdIjZ2GYwVlvkowQ5mz+yfVZ/wPv3X46MRppcfl8+9hYmrniBk75enXQfAlh6wEA+6X4Q3+zdjUV9qpm48kUmrngBKQSeSBif001JOGQ7IAmKT5tqFaTdDdaxdvXe3ojO5StfTPmqRgrB6WsX0/fM3zLx+KoWTbAVilyQycrPycDXUsptUkodeB44NjvDSp/WvNLfovy+tpaxt0yiNOjboy7Rg5SH/Ex/8S7WHTUsschlhQSGbv4Uh5T80KET7zwyiUtWz08EL11z4A6rS/B8UKYHOTK0IzbbzrFySqGIk0kg/xYYKoQoFUIIYCSwPjvDSo9CrPSbeaO0wOhHbWEpWuIUHNFjH7ChshCAU0qu+GAeM5+5lfLQHtmhJxLGFY3gxH4LuGIlXhxV74y1mc5UoZLO+xXvunS1+4ecK6cUijiZ5Mg/EEI8B6wGwsC/aUihFIq8r/Q38kZ5dF5fJv79Brwd9265XfPy+9ULCPztdpxjzsJpkc/fuWgxImIvr4vNbdo6fpeHVw4+nm3l+9C5dic1X7xHqYHLoB3SWTCOCsEznQdyUc0pOVVOKRSNySgNKqWcAkzJ0lgyJq8r/fHg7A8xLBwk9KGG9ty98PLLcOqpe7YzlUNC5Nln8DnclEZaqlTqnR5OWbfU0FNFYU6pHmTIf9bwdcfurOhzJNEv3s/JceJBPv7X73ARcTiZMH4qAx57KufKKYWiMcW2nmVJ3lb6DYKzW0YhFEKedhri9df3BHMLOaQWiVCCcUrGIaNITcPk4XaP2WxZAr1+/oFeP//A8K9XE3Q48Tk9IEh5Zp5MovjvrgfyZaee/FRSkXCX9LlLOGXxCtW8QZFX2lQgzxtz5yIjEcMfugA480zYvj12+Zyksw/Ego/P6aYsHEqoVt7oO4Sz1y3OzfhbGemkMOx0yompT8LUOR3cdeJlDPl2DWd8vjRrhlkvDDyZuYPPaHJ/5xIX/l5V1K/yUqaaNyjyhArk6bBhA8LnM31YBoOIO+6Au+6y1dmncV43ns8f++mb1Hz+nmE3mHSJB8yg5sAdNT4RFYIIAkHM+CfdMVmdDFwyQsjh5r2qIzl544q0c+bN6bNfOZ/dMarF/bNe74z81/2Gz7HlhqlQpEjbNc3KIXrvPujCXBMsAP7v/6CuzlZnn1I9iOzalQUXXMPaUeOoiXzPDe/OMu0GExfjh4WW8CAHCDqclnZaYaHxdu9BvN/r8JQqRHMt/nci2dJhv4wrUc3wRMJUh3dQre+wFcTtvF4BhL7Z1EKtpDxSFIVAzcjTYE7lUM7TNFwR8x+jFILwnKf4y9aeSTv7xCVr514xDLZuJVx1Ms5QywXQxhWcIaER1RxMOvNG9vXXUrlrK9+Vd+KWRTNwm1SDumSUTd0PpNQlkF+vtlXhOPOIGi749I2cLrpKYP/d23O2/6DDyehzhuHSBL53nze8OgpqTjZ27M628n0Y+u0a0/cwTr3Lw1d7dW2hgFIeKYpCoGbkKRKfcV0+9hbLmZsIhVj77urEj/r4Kx8l6DDOjCYKlZYuRfbujcMgiEMsgMeDr1tG8UZ0HnzxLjoE6/ihYl+61W5jbZfepuOqd3k49+yhjFlmr2Ix6HAScbp4vPpM6lxefA367GwjAFcO5/0iKnlh2Vc80/kw06sj3eni0nNv542+RyNMtP2NiffWbK6Aiiun4j03144al7jSsuuGqVCkioh5lueH6upquXLlyrwdLxfMWLKRu15dTzgKN701nctXvmQYFOtdHpZMvpm/Vw0nKiWff1/LUf9Za+qGt/mAA1n2j0sRaVT/NZ6pW+WK61xeHj35Yq5c+Lhh7r2xlM4b0Qk63XjjC7AIZh81mgHff8mwTR9lbcEwPu5s0Hx/LTxohMZdwy/lhsWzWnwG8fvd4VCiItaIoMOJ7nDFHAz7Hs6HN52sSu8VOUcIsUpKWW32uEqtpEhAj7BvuYcfdwf56/G/5IKPF1JucKkuhcaCfiew4IphzFiykbtf+8zycvvCTxYS1sNpqRmaKzWMkMAX+/bk6tdm4DA5eQtgwz77c8Du7THFR4MLY7xK9IoP5rGjtEMaIzQeTy4WW8NCQyBxyqYt2OKv4eZFj/LUwFOp0P385O3Ahk49ebt3NW/PmES5DafD93sdzuSzblApEkWrQgXyFInr1Bd8+h2ffw8Tzp1mOsv+dFMdAT1CQI9w+F4Ojlz2Oh2/+5ad+/fknyMuokPnjlQ1XOofuXI7rkBqlqmpIIAjv0/edLnvT9+ZpoCcSLr4fs5oHGEg7HCC0BInimwhiK0DWOGJ6Fz27wXUuzwIzcGUSffwyx/X2Oq6FHQ4+WjISKoquyTuUykSRWtApVbSJD7L1iOS0pDfeFHLIbhhVD8msgVZU4M/oFOqBwg6nAgpWX/+RA5/6M9QUYH+8HT031xruBCX7RRErmhe7Wj0+Gf79uK9qiMS9rCZHMfu/ZZUVMSqLP/616SbhjQHT736EZeeOiDVoygUGaFSKznCrh1AeNcuuLBpFWg8Pz1wznTkS3MQr75q2SVI1xxEJXhkfrTf6aY9wmj8VFJBZ7/xrF0AfXdtYVHPMdR/7EmkO7I1tnTGLKNRIjt2EEqi9ZfAjMFjeChJZx+FohCoQJ4mtu0AZswwLdEXAHV1yJoaHrh6Ni+Pn8rsubdS0qhRsgRcaRTvxANeSGgx+4AUSPVYEWLyp4jDQWf/z5bBNgr0774X0qYzYeNZfi4Q9fWsC7ronUTrX+/ycv+x56OrvLiiFdKu5Ye2LWgzYc0a0xL9OLoeZsTHb7N+vyqiQrRYvEwlsIYQBB0uZlSfxQNDx/HSoSfis+FpngnxMca15smKc1iwgLerjkLXHCQ7RYlGf1N9L+zgc3l5qdbLE0fWENIcieKq+Ikj4HTHCnnOnUbAU0LfzuUqL65odbTfGXkjC9oVH1Qz7ObJsXxpNlm6FPnQQ4B1AHIH/BwR3I73q/fQ0lizaDxrdSPxI7ngk4VcNn4qm3r05fR7l6UzetukElwlcNw3H+Fq1HatoM2dZZTfvvkYAok7GiHocBISDt6rPIINnQ5oYobl0gTjBh2gZuOKVkf7XOxssKCNLz76XF5KvC7EK6/A8cfb3o1lG6/aWuje3VZXGJ/Lw+YTTsG7cgU9f/4h1Vdjvl9PKcdd8wR9tn7JzGen4tGDSVUdbZ14qilZb9M6dwknXPskPncJAB1KXOxX4WHUgK6ql6Yi76jFzuaY+oOnaPqfbEZvYV/bnBI9yIFvzc/6rNQpJKevXcxTh53KkMmzuW3hg4xZ9w7ONIJ5psoZO89PmHo5nLgj4RykUTwsaGRO5gmHuGHx44bblrk0Vh/8E0w8J8ujUCiyT/vLkVu0V5PRKMydm3wfS5cmb+NlYV8bx+fyJIKXnaCV6rWTO+BnsO97+nfrQEWnvZlyypUETPLlyfYtgEgardOCmoMwwtZrFMCqbgdzx0mXU+/y2tp/Ku9JVGj845xrEyXzA+VuU+WM8g1XFBPtL5Bb+YPb+fE2ntE3yNVK9UCstL6mBurqgJhDolkwCmpO3u49iFcOPi6xuGaHoObk2w6dbW8vgbPf+xcLjhKcP/gA/N7ShCtffAE0pDkaqiGtiUJ6M3mhobvsebTUuzwsHnYm/6wezYRzpzVxDzRDALrJCSYe5Bs7D24JO/jn5Uez4JphjBk/HJ/JZ+RzedGretsat0JRaNpdINd798nsx2tzRj+nciiYSNrc0TDPnzAe2aUrHgtfjz3jigWiX17wR/5x7HlJg1scAQhdh1Gj2CcawqEJVvboz5VjbkSLRmP54miEiBC2ZuTJkMQ0743H/OrBx1JiUy8uhcbGEaMT4xwyeTbTRk7i7d6DCDqMs4A+l4eIyckw6HAxffAYpo2cxEmXP0yfHZv5r7ce46Wrb4PaWkuL4YSRmUJRBLS7QJ7xjzfJjD78+RcE9AiL5r6BI6wbBkgB3DlnGr+oGWwaoCAWGMNCMPOo0QyZPJuVPfqz4JBhtjXYif3U1dH/8b9T7nFybGmQR+fdjjeiJ/TlHhs6dTuWt49Un8VNp07mgaHjmDpyEkMmz2Z5z4GmJ574e+N3uBIz5jc21dF7vzL2LnXRq1dn1o4ax22/vBXd1DlS4/Kxtxh6f//y/Du4a+TlRA86kMWPXsmtb03nqg/mMfbJvyC7dWfR3DeUb7iiTdCuVCsBPcKQP77JQV9+zMxnpuCKhvFEwjFHO83JhHOnJXW0syqlD2kONp5yJqsm/Z6zzhthaKYVp97p4YULfsPZc+6jNInXt89TysW3P4/PXbLHRfGZKXjCIdsqlKimMf/AY/nFl8vRTBYSM5UBPjB0HPcMn0DXDh72LfcQlZIft2xj8X0XGxpS6ZqDJ44YxWedeyckfnuH/fxu50f41n3GgOHVDL7+Sob87YPYZ2biabOyR39Tm4S9w34+fHACbl/Lk2+du4Qhk2cDWFssHF9lrVBSKHKMUq00Im76b4U/SeWeVSm9OxrhgLdeoe+iBUiLphMAZeEggc83YCd0ljgF8zpuZsZBJ3H3a58BsebMqeSsRTTKmZ8vtd7G9t5a4nN62Nn1APp36xCT6A3uyju3/Z31S1bzxJE1XLx6AQJpGIQ9DoEQglN++Jz7nrgJGY1SpgfwrV6Adv8dHDp2CsstnCMFUNFpb9aOammTcOqyd8EkFeZAMum7FSw8ZrSpxYI/FM5PzYFCkQHtKpDHXQhnPzetyYzaE4nNzGc/N42Lb3/etHIv3lTi5fFTmfnsVDQZbdE6rMxAk2xESDjYq74WB8mDcXwRNlB1QsP4p1KSonOg3Rx3usFck1E2nTyaBZOHNah6BjE4oHOiHkhotmcdNRqEaDHrvW5UPyYe3gm6nwfBPb1QY7JQeOyZqVx8+/MEPF1MA66pvnvLfDBxlSwJBbi2UuPaa4aZv7CG1zIooDOs4eQiH/zflGsOFIpc0q4C+dUjDuTqjYuRTgEG8TY+82XEaYbPb97G67Y3HuTMte8YepkkC4pSQF15B1vNlSUQ3r/bnvG3wqKeVw4+jiXfBQns3IW3QdVT1vBYXOI34aNXGwJyactZr4XuPvG5TJyY8risml8n7WifrZoDhSLHtKtADmQkP2zueCi7dMW9xjioJpXzaQ627LM/QYfTVjD/8JudHBcffyg7XeCbE9OKC9PGE2bUO90s7zmQUCTKirsf4vh0AvLrMzKThZpglQpL2tHe4uQio1HE3LlpnVwUimzT7lQrmcgPrx5xIAuuGZa4WemQA043uoWsLyoEwbBE15KfSwWw/sN1BPQIeu8+lkqXsBAEHM6ECiOVkFzv8vDSIcMs92+E1BysGHIy/fbvQOmmjWkF5IxloQZk3NE+05oDhSJPtLtAnk3tsNW+wpqDfx5RYzozL9ODdK3bzoRzp+Fzui0DbuOO7XMqh1oG/4DTw/FXPsa0kZN4t9cRtl8LxHTcd4643FTqB7ETg1GhzQ7hZt5VxzLwpOq0AnIuNN3NU2HTRk7igaHjmNYgjVzZo39icduIXJxcFIpc0K4CeaozNCubWzv7Wt+lt6mGut7l4Zu9u7GyR3+qf/NP7jhxImGTQBbv2L7bH+LPy75jwrnT8DcL/hLwOd1MOHcaO8o78vFp57C2ax9bi5dBhzMx5h/LO7Z8TU43AYeLlw45nhf6DWdJr8N5u2oQdw2/rEVATCcgZzxzNiHTjvaqYEhRLLSrHHnzGVpcyvZdeSdAMvLLDzlw5xaeebsblxxTaSk5M9tXY0XG552ruGXRDMOxSARl0RDXv/M4/+nYnaePOI2Pux9kqpXeIdyUuJz4grGgExEaIc2BJxohjCCsObjinJtZ2aM/AH08UTrX/URIc1h2hYemDYUBw9e0tUMnHnrhziZjG7xlHd9XHszWwwYBUBvQeayRqsfodXxh0GHHznuZTqNj280/DGiuULL7WhSKQtCuCoLuX7SBV9d83+S+Q7/6hGkPX4eMRhI/VLcQOJ0afj1qanNrtK/GRKXcU7zTLBAIGdO0SEHDfV6kEEwYP5V1nXubFqcc17cT33z9PfPvPt+wwKbO5eXPJ07g8C3rqfnifcISypIVG7k8LOp/Av/xdOD7/Xow/5BhOPbei/0q9lxJlAR8zL71HEobSQMTVFQk1Bsp9TFtFJCTvZdx8mkhm+5rUShyQbKCoIwCuRBib2AGMIDYgPlKzgAADRtJREFU1f2vpJSmXQwKHchbkIJnONAkaCXDLBB8V96J6xfPNKz6jFdwBjylBntsCGQbFyN/+1vDRTgJ6A0WsHaJpWQ8lIWD5r7sM2aYH7OsDHHffTBxYqsMyOnSll6LovjJdWXnfcBrUspxQgg3YByBWispeIZDapIzs+bMpy6bj8PkgLb00lYyPbAM4jHvFg2XjOJzeSjRY71B40VMphppi3Z1jdUbmaQyWhtt6bUo2j5pB3IhRAfgBGACgJQyBKRWblhobHiGNyYVyZlpINgyH0LGHix29m9V4JIMASypPJLPulTRuW4noz5bSplBhWiTE1aSdnX1Li+iZ2WRncEVirZFJqqV3sA24HEhxL+FEDOEEGXNNxJCXCGEWCmEWLlt27YMDpc5zVUoVvIyI7IhObM6pgT0sPXCpJWSIhn1Lg8fHz2SBRdcg+zS1TCIQ6MTSm0tsqYGEQyaXrW4IjovLPvKfnpKoVBknUwCuRM4CnhQSnkkUA/c0HwjKeV0KWW1lLJ6v/32y+BwGVJby4qb76HnPbex4uY/JfWjNiIbkrM5lUORJscUgPzHPxLNKZpjJtMLOpy2Cn+k0Oh42cX2myrMmkUkYFxFGteTu6MRznr6b8huzTokKRSKvJFJIN8MbJZSftDw/+eIBfbWh1FrNgs/ap/Tjc/pybpHdTwQzz6yxjTwhsNR9DlPGT5mVuCSrDVavdPdYvzJNNJv1nmQ//VfOHWTWTt7Ui1lehBR17RDkkKhyB9p58illN8LIf4jhDhYSvk5MBJYl72hpUcL32gL46N//PMWhkyebahdBhOP6jT0zHEa2+iaXQeU6gE+fnc1h19h/NqaL6B+2iBz/Gafbjzy/O1oMoo7GsHn9KDJKK8cfBzLew5sMv5Z73/DPyw00leddSMP3nhlrLtQCij/EYWiMGSqWvkN8M8GxcpG4LLMh5QBRr7RFsqU5n7U79QG2e3fE7xeGnQ6HUpc7FfhaenWlwbxQBys7E39ao9h4996l4cfu/QwfL7RAuqMJRt585F5PPjinUSEwBuJEBIamoxy+dhbWFp1FALo3MFDVXnsCmPZVzssC3DOWP9ug9Y9NZT/iEJRGDIK5FLKjwBTbWNeWboUWVPT0jf6jDNMlSm2/KizSDwQzzp4L+S/7jfcRgqNraedZXufkZ9/5rFnplLaqEDILaMQiTL9xbsSuvTGeuf7F21gW138JNKhhcd39Sc7KLNQxZhZ9Ca1hVUoFDmhbZToW6RP5Lzn8Ts9lBo0fChE4Ml26fek71cl91dvlupIppHWPeupf/d5w2Ae1BxIBN5oy6uSpLawCoUiJ7QN0yyLzvZhIdBMGjEUwvjoyeWb8IXCaTvytSAHVqtWyhrd6ebycbeqhsUKRSuibczILYKZK+Dn5UNP5NQvP2gVxkeRn3/msvVv0fG7b9m5f0/+fVINa72x64h08vAZdcAxwM4VQ7bNrRQKRWa0iUBuFczqXR6W9xzIzadNLnzgWbqUKy6swR/Q95hxvTUjo/6PGXXAMcCOEyFAB5Nmx5D+YrBCoUiPNhHIrYKZKxJhL3QO7Vph3Sk91+Sg/2MurFbNPGLAZrNjhUKRd4rSxraxVhxgyB/f5KAvP24SzOKvShCblZd63IhXm858W2jOc4lNB8GUdqmsVhWKdkGu3Q/zTzOt+MYRNU1SAWM/fYtbFj3SpJlCmR4EPdh05mukOW/UOCLr5GBR0u7sOd+pjryeIBUKRZEFcgOt+NF/v4M1v76bdX0GAh3o9F0HIk4XhFoqJxKVhwcfbKw5zyBXnYxsL0pCK7VazfcJUqFQFFEgN80xw58ev3HPTDuZTezatfC732U1V22HbC9KtkrMirJyeIJUKBTFpCO30IrLaBTmzgWSdz4Pb99uaz/ZJFfNhVsVjU+0DVcdpXoAUavMtBSKXFM8M3KbOeZkM9/1QSeHZTlXnYxcNRduVVh42igzLYUitxRNINd79yHidOM1aIYQcLpxVPUmYkOO1//nrfTJcq46Ga11UTKr5GAxV6FQ2KNoAvkznQ/jQpOONp5wiDldDsdvY+b7eecqfr9wuuF+cpWrbpWLklkmF4u5CoXCHkWRIw/oETY8PpeAwzgUBBwuvnj0KWoDOgd1qaB/tw5UVXZh7ahxLLjgGtaOGkdVZRf67V9Bvae0beeqC0SyRhX59rRRKNoTRTEjf3L5JvbftoWSiHGjg5KIzv7bt+AqcbPAwpI2XkDTpnPVBSAXFaYKhcI+RRHIA3qEcK8q6leZN2Pw96oinCTH3C5y1QWgXSzmKhStmKII5FePOJBZ+i8tmzF0vOxiLk2Shy6mXHUxVUeqE6RCUViKwmsloEcM/VSaXLr3PZwPbzq51Qc9W9TWsuSO+1mzeBUDhqvqSIWivZPMa6UoAnm7ModqqI5sYnXrdanqSIWiHdMmTLPazaV7DqxuFQpF26coAnkx5bYzQlVHKhSKNCgKHXm7QVVHKhSKNFCBvBWRzPBLr+qd5xEpFIpiQAXyVoSqjlQoFOmgAnkroV1Y3SoUipxQFIud+aKQRTiqOlKhUKSLCuRxCtyirN1ILBUKRdYpioKgnKOKcBQKRSsmWUGQypGrFmUKhaLIUYHcZi9QhUKhaK1kHMiFEA4hxL+FEPOzMaC8o4pwFApFkZONGfm1wPos7KcgqCIchUJR7GQUyIUQPYBfADOyM5z8o4pwFApFsZPpjPyvwHWAcZIZEEJcIYRYKYRYuW3btgwPl11UEY5CoWgLpK0jF0KMBn6UUq4SQpxotp2UcjowHWLyw3SPlwtUEY5CoWgLZFIQdBxwphCiBvACHYQQT0opf5mdoeUeVYSjUCjaAlkpCGqYkf+PlHK01XattiBIoVAoWjGqIEihUCjaOFnxWpFSvgO8k419KRQKhSI11IxcoVAoihwVyBUKhaLIUYFcoVAoihwVyBUKhaLIUYFcoVAoipy8NpYQQmwDNmVpd52A7VnaV74otjEX23ih+MZcbOOF4htzWxhvLynlfmZPyGsgzyZCiJVWAvnWSLGNudjGC8U35mIbLxTfmNvDeFVqRaFQKIocFcgVCoWiyCnmQD690ANIg2Ibc7GNF4pvzMU2Xii+Mbf58RZtjlyhUCgUMYp5Rq5QKBQKVCBXKBSKoqcoA7kQYm8hxHNCiM+EEOuFEK22saYQ4mAhxEeNbruFEL8t9LiSIYT4nRBirRBijRDiKSGEcYfqVoIQ4tqGsa5tre+vEOIxIcSPQog1je7rKIR4QwixoeHvPoUcY2NMxju+4T2OCiFanaTPZMx/aogVnwgh/iWE2LuQY2yMyXhvbxjrR0KIhUKIbsn2U5SBHLgPeE1KeQhwOLC+wOMxRUr5uZTyCCnlEcAgwAf8q8DDskQI0R24BqiWUg4AHMD5hR2VOUKIAcCvgSHEvg+jhRAHFnZUhswETm923w3AW1LKA4G3Gv7fWphJy/GuAc4B3s37aOwxk5ZjfgMYIKUcCHwB3JjvQVkwk5bj/ZOUcmBDzJgP3JpsJ0UXyIUQHYATgEcBpJQhKeWuwo7KNiOBr6SU2apuzSVOoEQI4QRKga0FHo8V/YDlUkqflDIMLAbOLvCYWiClfBfY2ezus4BZDf+eBYzJ66AsMBqvlHK9lPLzAg0pKSZjXtjwvQBYDvTI+8BMMBnv7kb/LQOSKlKKLpADvYFtwONCiH8LIWYIIcoKPSibnA88VehBJENKuQX4M/At8B3ws5RyYWFHZcka4AQhxL5CiFKgBjigwGOySxcp5XcADX87F3g8bZ1fAa8WehDJEEL8UQjxH+Ai2uKMnNhM8SjgQSnlkUA9rety1BAhhBs4E3i20GNJRkOe9ixiPai7AWVCiFbbVFtKuR64m9gl9GvAx4DqmK1oghDiJmLfi38WeizJkFLeJKU8gNhYr062fTEG8s3AZinlBw3/f45YYG/tjAJWSyl/KPRAbHAy8LWUcpuUUgeeB44t8JgskVI+KqU8Skp5ArFL1Q2FHpNNfhBC7A/Q8PfHAo+nTSKEuBQYDVwki6t4Zg4wNtlGRRfIpfz/7dyvSwRBGMbx71MUrKLxguWq0SgYFMM1EdMhGC5bxCT+DVa7YFK7yWLTJCaDVzT4qwgi+BpmQFxZvDaOPJ+yy7C7PEx4h50XJu6AoaRuHloArgpGGtUaFWyrZLfAnKQJSSLN8Z9tKANIms7XDqkZV8tcnwD9fN8Hjgtm+ZckLQFbQC8iXkvn+U2jUd8Drn99p67FKZE0C+wDY8ANsB4RT2VTtcv7tkNgJiJeSucZhaRdYJX0K3oBbETEW9lU7SSdAZPAO7AZEaeFI/0g6QCYJx1Teg/sAEfAIdAhLaArEdFsiBbRkvcR2AOmgGfgMiIWS2Vsasm8DYwDD/mx84gYFAnY0JJ3GegCH6Rjvwe5b9X+nRoLuZmZfalua8XMzL5zITczq5wLuZlZ5VzIzcwq50JuZlY5F3Izs8q5kJuZVe4T2oav7hs1PygAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "lowDMat , reconMat = pca(dataMat, 2)\n",
    "drawScatter(dataMat, reconMat)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 实例：利用PCA对半导体制造数据降维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 用平均值代替空值\n",
    "def replaceNanWithMean():\n",
    "    datMat = loadDataSet('secom.data', ' ')\n",
    "    numFeat = shape(dataMat)[1]\n",
    "    for i in range(numFeat):\n",
    "        # 求每个特征非NaN的平均值\n",
    "        # isnan 返回True（1）、False（0）值\n",
    "        meanVal = mean(datMat[nonzero(~isnan(datMat[:, i].A))[0], i])  \n",
    "        # 将NaN值用平均值代替\n",
    "        datMat[nonzero(isnan(datMat[:, i].A))[0], i] = meanVal\n",
    "        \n",
    "    return datMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataMat = replaceNanWithMean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 5.34151979e+07,  2.17466719e+07,  8.24837662e+06,  2.07388086e+06,\n",
       "        1.31540439e+06,  4.67693557e+05,  2.90863555e+05,  2.83668601e+05,\n",
       "        2.37155830e+05,  2.08513836e+05,  1.96098849e+05,  1.86856549e+05,\n",
       "        1.52422354e+05,  1.13215032e+05,  1.08493848e+05,  1.02849533e+05,\n",
       "        1.00166164e+05,  8.33473762e+04,  8.15850591e+04,  7.76560524e+04,\n",
       "        6.66060410e+04,  6.52620058e+04,  5.96776503e+04,  5.16269933e+04,\n",
       "        5.03324580e+04,  4.54661746e+04,  4.41914029e+04,  4.15532551e+04,\n",
       "        3.55294040e+04,  3.31436743e+04,  2.67385181e+04,  1.47123429e+04,\n",
       "        1.44089194e+04,  1.09321187e+04,  1.04841308e+04,  9.48876548e+03,\n",
       "        8.34665462e+03,  7.22765535e+03,  5.34196392e+03,  4.95614671e+03,\n",
       "        4.23060022e+03,  4.10673182e+03,  3.41199406e+03,  3.24193522e+03,\n",
       "        2.74523635e+03,  2.35027999e+03,  2.16835314e+03,  1.86414157e+03,\n",
       "        1.76741826e+03,  1.70492093e+03,  1.66199683e+03,  1.53948465e+03,\n",
       "        1.33096008e+03,  1.25591691e+03,  1.15509389e+03,  1.12410108e+03,\n",
       "        1.03213798e+03,  1.00972093e+03,  9.50542179e+02,  9.09791361e+02,\n",
       "        8.32001551e+02,  8.08898242e+02,  7.37343627e+02,  6.87596830e+02,\n",
       "        5.64452104e+02,  5.51812250e+02,  5.37209115e+02,  4.93029995e+02,\n",
       "        4.13720573e+02,  3.90222119e+02,  3.37288784e+02,  3.27558605e+02,\n",
       "        3.08869553e+02,  2.46285839e+02,  2.28893093e+02,  1.96447852e+02,\n",
       "        1.75559820e+02,  1.65795169e+02,  1.56428052e+02,  1.39671194e+02,\n",
       "        1.28662864e+02,  1.15624070e+02,  1.10318239e+02,  1.08663541e+02,\n",
       "        1.00695416e+02,  9.80687852e+01,  8.34968275e+01,  7.53025397e+01,\n",
       "        6.89260158e+01,  6.67786503e+01,  6.09412873e+01,  5.30974002e+01,\n",
       "        4.71797825e+01,  4.50701108e+01,  4.41349593e+01,  4.03313416e+01,\n",
       "        3.95741636e+01,  3.74000035e+01,  3.44211326e+01,  3.30031584e+01,\n",
       "        3.03317756e+01,  2.88994580e+01,  2.76478754e+01,  2.57708695e+01,\n",
       "        2.44506430e+01,  2.31640106e+01,  2.26956957e+01,  2.16925102e+01,\n",
       "        2.10114869e+01,  2.00984697e+01,  1.86489543e+01,  1.83733216e+01,\n",
       "        1.72517802e+01,  1.60481189e+01,  1.54406997e+01,  1.48356499e+01,\n",
       "        1.44273357e+01,  1.42318192e+01,  1.35592064e+01,  1.30696836e+01,\n",
       "        1.28193512e+01,  1.22093626e+01,  1.15228376e+01,  1.12141738e+01,\n",
       "        1.02585936e+01,  9.86906139e+00,  9.58794460e+00,  9.41686288e+00,\n",
       "        9.20276340e+00,  8.63791398e+00,  8.20622561e+00,  8.01020114e+00,\n",
       "        7.53391290e+00,  7.33168361e+00,  7.09960245e+00,  7.02149364e+00,\n",
       "        6.76557324e+00,  6.34504733e+00,  6.01919292e+00,  5.81680918e+00,\n",
       "        5.44653788e+00,  5.12338463e+00,  4.79593185e+00,  4.47851795e+00,\n",
       "        4.50369987e+00,  4.27479386e+00,  3.89124198e+00,  3.56466892e+00,\n",
       "        3.32248982e+00,  2.97665360e+00,  2.61425544e+00,  2.31802829e+00,\n",
       "        2.17171124e+00,  1.99239284e+00,  1.96616566e+00,  1.88149281e+00,\n",
       "        1.79228288e+00,  1.71378363e+00,  1.68028783e+00,  1.60686268e+00,\n",
       "        1.47158244e+00,  1.40656712e+00,  1.37808906e+00,  1.27967672e+00,\n",
       "        1.22803716e+00,  1.18531109e+00,  9.38857180e-01,  9.18222054e-01,\n",
       "        8.26265393e-01,  7.96585842e-01,  7.74597255e-01,  7.14002770e-01,\n",
       "        6.79457797e-01,  6.37928310e-01,  6.24646758e-01,  5.34605353e-01,\n",
       "        4.60658687e-01,  4.24265893e-01,  4.08634622e-01,  3.70321764e-01,\n",
       "        3.67016386e-01,  3.35858033e-01,  3.29780397e-01,  2.94348753e-01,\n",
       "        2.84154176e-01,  2.72703994e-01,  2.63265991e-01,  2.45227786e-01,\n",
       "        2.25805135e-01,  2.22331919e-01,  2.13514673e-01,  1.93961935e-01,\n",
       "        1.91647269e-01,  1.83668491e-01,  1.82518017e-01,  1.65310922e-01,\n",
       "        1.57447909e-01,  1.51263974e-01,  1.39427297e-01,  1.32638882e-01,\n",
       "        1.28000027e-01,  1.13559952e-01,  1.12576237e-01,  1.08809771e-01,\n",
       "        1.07136355e-01,  8.60839655e-02,  8.50467792e-02,  8.29254355e-02,\n",
       "        7.03701660e-02,  6.44475619e-02,  6.09866327e-02,  6.05709478e-02,\n",
       "        5.93963958e-02,  5.22163549e-02,  4.92729703e-02,  4.80022983e-02,\n",
       "        4.51487439e-02,  4.30180504e-02,  4.13368324e-02,  4.03281604e-02,\n",
       "        3.91576587e-02,  3.54198873e-02,  3.31199510e-02,  3.13547234e-02,\n",
       "        3.07226509e-02,  2.98354196e-02,  2.81949091e-02,  2.49158051e-02,\n",
       "        2.36374781e-02,  2.28360210e-02,  2.19602047e-02,  2.00166957e-02,\n",
       "        1.86597535e-02,  1.80415918e-02,  1.72261012e-02,  1.60703860e-02,\n",
       "        1.49566735e-02,  1.40165444e-02,  1.31296856e-02,  1.21358005e-02,\n",
       "        1.07166503e-02,  1.01045695e-02,  9.76055340e-03,  9.16740926e-03,\n",
       "        8.78108857e-03,  8.67465278e-03,  8.30918514e-03,  8.05104488e-03,\n",
       "        7.56152126e-03,  7.31508852e-03,  7.26347037e-03,  6.65728354e-03,\n",
       "        6.50769617e-03,  6.28009879e-03,  6.19160730e-03,  5.64130272e-03,\n",
       "        5.30195373e-03,  5.07453702e-03,  4.47372286e-03,  4.32543895e-03,\n",
       "        4.22006582e-03,  3.97065729e-03,  3.75292740e-03,  3.64861290e-03,\n",
       "        3.38915810e-03,  3.27965962e-03,  3.06633825e-03,  2.99206786e-03,\n",
       "        2.83586784e-03,  2.74987243e-03,  2.31066313e-03,  2.26782347e-03,\n",
       "        1.82206662e-03,  1.74955624e-03,  1.69305161e-03,  1.66624597e-03,\n",
       "        1.55346749e-03,  1.51278404e-03,  1.47296800e-03,  1.33617458e-03,\n",
       "        1.30517592e-03,  1.24056353e-03,  1.19823961e-03,  1.14381059e-03,\n",
       "        1.13027458e-03,  1.11081803e-03,  1.08359152e-03,  1.03517496e-03,\n",
       "        1.00164593e-03,  9.50024604e-04,  8.94981182e-04,  8.74363842e-04,\n",
       "        7.98497544e-04,  7.51612216e-04,  6.63964296e-04,  6.21097621e-04,\n",
       "        6.18098599e-04,  5.72611397e-04,  5.57509228e-04,  5.47002380e-04,\n",
       "        5.27195075e-04,  5.11487996e-04,  4.87787872e-04,  4.74249070e-04,\n",
       "        4.52367688e-04,  4.24431099e-04,  4.19119023e-04,  3.72489906e-04,\n",
       "        3.34002143e-04,  3.38125455e-04,  2.97951371e-04,  2.79038287e-04,\n",
       "        2.77054476e-04,  2.84845901e-04,  2.67962797e-04,  2.54815125e-04,\n",
       "        2.29230595e-04,  1.99245436e-04,  1.90381389e-04,  1.84497913e-04,\n",
       "        1.77415682e-04,  1.68160613e-04,  1.63992030e-04,  1.58025552e-04,\n",
       "        1.54226003e-04,  1.46890640e-04,  1.46097433e-04,  1.40079891e-04,\n",
       "        1.35736724e-04,  1.22704035e-04,  1.16752515e-04,  1.14080846e-04,\n",
       "        1.04252870e-04,  9.90265090e-05,  9.66039062e-05,  9.60766568e-05,\n",
       "        9.16166330e-05,  9.07003470e-05,  8.60212632e-05,  8.32654024e-05,\n",
       "        7.70526077e-05,  7.36470020e-05,  7.24998301e-05,  6.80209909e-05,\n",
       "        6.68682698e-05,  6.14500422e-05,  5.99843175e-05,  2.98089202e-05,\n",
       "        5.49918002e-05,  5.24646951e-05,  5.13403843e-05,  5.02336252e-05,\n",
       "        4.89288494e-05,  3.43901591e-05,  3.57776535e-05,  4.51104475e-05,\n",
       "        3.80307292e-05,  3.94822839e-05,  4.29823764e-05,  4.18869716e-05,\n",
       "        4.14341558e-05,  2.72388357e-05,  2.42608885e-05,  2.30962279e-05,\n",
       "        2.27807559e-05,  2.14440814e-05,  1.96208174e-05,  1.91217363e-05,\n",
       "        1.88276186e-05,  1.66549051e-05,  1.46846458e-05,  1.43753346e-05,\n",
       "        1.39779892e-05,  1.21760519e-05,  1.20295834e-05,  1.13426750e-05,\n",
       "        1.09258905e-05,  1.02782987e-05,  1.01021803e-05,  9.72678787e-06,\n",
       "        9.64538283e-06,  9.23630199e-06,  8.93991854e-06,  8.34247902e-06,\n",
       "        5.91044552e-06,  7.36188582e-06,  7.20354826e-06,  6.69282813e-06,\n",
       "        6.49477814e-06,  5.67034891e-06,  6.00244889e-06,  5.31392220e-06,\n",
       "        5.09342483e-06,  4.65422046e-06,  4.45482133e-06,  4.11265576e-06,\n",
       "        3.48065951e-06,  3.65202837e-06,  3.77558985e-06,  2.78847697e-06,\n",
       "        2.66299624e-06,  2.57492502e-06,  2.39210232e-06,  2.06298820e-06,\n",
       "        2.00824520e-06,  1.76373602e-06,  1.58273269e-06,  1.32211395e-06,\n",
       "        1.49813697e-06,  1.44003524e-06,  1.42489429e-06,  1.10002716e-06,\n",
       "        9.01008863e-07,  8.49881105e-07,  7.62521870e-07,  6.57641103e-07,\n",
       "        5.85636641e-07,  5.33937361e-07,  4.16077214e-07,  3.33765858e-07,\n",
       "        2.95575264e-07,  2.54744632e-07,  2.20144573e-07,  1.86314510e-07,\n",
       "        1.77370960e-07,  1.54794342e-07,  1.47331683e-07,  1.39738552e-07,\n",
       "        1.04110968e-07,  1.00786519e-07,  9.38635090e-08,  9.10853309e-08,\n",
       "        8.71546323e-08,  7.48338889e-08,  6.06817433e-08,  5.66479199e-08,\n",
       "        5.24576912e-08,  4.57020638e-08,  2.89942623e-08,  2.60449405e-08,\n",
       "        2.10987990e-08,  2.17618741e-08,  1.75542294e-08,  1.34637028e-08,\n",
       "        1.27167436e-08,  1.23258200e-08,  1.04987513e-08,  9.86368002e-09,\n",
       "        8.49423604e-09,  9.33428146e-09,  7.42191739e-09,  6.46870773e-09,\n",
       "        6.84633833e-09,  5.76455806e-09,  5.01137909e-09,  3.48686377e-09,\n",
       "        2.91267193e-09,  2.77880624e-09,  1.73093437e-09,  1.42391199e-09,\n",
       "        1.16455056e-09,  1.11815878e-09,  9.24975881e-10,  1.80003542e-10,\n",
       "        1.97062401e-10,  2.61932795e-10,  6.95073590e-10,  6.13272275e-10,\n",
       "        5.27582108e-10,  1.07423294e-14, -1.54735057e-15,  2.37467042e-16,\n",
       "       -1.28364788e-18,  3.78369892e-18,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00])"
      ]
     },
     "execution_count": 147,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 观察最后的结果，可以发现很多特征值为0，表明其是不重要的特征可以省略\n",
    "# 同时前面的特征值可以筛选出最重要的，从而实现降维\n",
    "meanVals = mean(dataMat, axis=0)\n",
    "meanRemoved = dataMat - meanVals\n",
    "covMat = cov(meanRemoved, rowvar=0)\n",
    "eigVals, eigVects = linalg.eig(mat(covMat))\n",
    "eigVals"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
